﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Xml.Linq;

namespace SocketServe
{
    public class Program
    {
        private static List<Socket> clients = new List<Socket>();
        private static List<string> usernames = new List<string>();
        private static Socket Server;
        static void Main(string[] args)
        {
            // IPv4 v6,套接字类型，流式套接字，协议
            Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            // 指定连接地址和端口号
            Server.Bind(new IPEndPoint(IPAddress.Any, 888));
            Server.Listen(10);
            Console.WriteLine("服务端已经开启成功了，等待用户的连接。。。");

            while (true) {
                Socket client = Server.Accept();
                clients.Add(client);
                Console.WriteLine($"新的用户连接{client.RemoteEndPoint}");
                Thread th = new Thread(() => HandleClient(client));
                th.Start();
            }
        }

        static void HandleClient(Socket client)
        {
            byte[] buffer = new byte[1024];
            string name="";
            try
            {
                int num = client.Receive(buffer);
                // 把字节转换成字符串
                name = Encoding.UTF8.GetString(buffer, 0, num);
                string msg = $"{client.RemoteEndPoint}注册为{name}";
                Console.WriteLine(msg);
                BoardCasts(msg, client);
                usernames.Add(name);

                while (true)
                {
                    num = client.Receive(buffer);
                    if (num == 0) break;
                    string message = $"{name}:{Encoding.UTF8.GetString(buffer, 0, num)}";
                    BoardCasts(message, client);
                    Console.WriteLine(message);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                client.Close();
                clients.Remove(client);
                usernames.Remove(name);
                string exitMessage = $"{name}:已下线";
                BoardCasts(exitMessage, client);
                Console.WriteLine(exitMessage);
            }
        }

        static void BoardCasts(string msg,Socket client)
        {
            // 发送消息
            foreach (var item in clients)
            {
                if(item != client)
                {
                    client.Send(Encoding.UTF8.GetBytes(msg));
                }
            }
        }
    }
}
